[Day11] 由左至右:海賊五皇魯夫、革命軍首領龍、海軍英雄卡普,這祖孫三代的組合會不會太強。。。
在 Ruby 裡,上下層的類別之間會有**繼承(inheritance)**關係,那麼,什麼是繼承關係呢?
繼承就是你老爸超有錢叫你不用去工作了(誤)
咳咳。。。我想一般人都沒有這種老爸,
我們先看一張國小自然課本裡的圖片好了,大家還記得林奈嗎?看出生物學家都是整理控了嗎?
覺得頭大?還是我找法律條文裡的繼承會不會好一點?(討打)
畢竟地球上的生物有百百種,因此如果不按照物種「共有的生理特徵」進行分類,怎麼知道哪一些生物的關係比較接近呢?(不知道好像也沒關係)
而 Ruby 裡的繼承關係也是一樣的,在 Ruby Guide 的文件裡有介紹到繼承的概念,簡而言之就是每個類別向上都還有自己所屬的類別。
舉個例子,譬如蘋果、柳橙各是一種水果,水果又是食物的一種:
class Food
end
class Fruit < Food
end
class Orange < Fruit
end
class Apple < Fruit
end
按1:在 Ruby 的世界裡,小於符號 「<
」 被用來表示「繼承」的意思。
按2:Orange
和 Apple
這兩個類別都屬於 Fruit
類別,而 Fruit
類別又屬於更上層的 Food
類別。
在物件導向的概念裡,如果這些類別的用途是同一型的,譬如 Orange
跟 Apple
都很適合打成果汁(?) 通常我們會把相同功能的方法移到「上一層」的類別,所以我會在 Fruit
這個類別直接定義一個 juicy
方法
class Fruit < Food
def juicy
end
end
o1 = Orange.new
a1 = apple.new
o1.juicy
a1.juicy
然後,只要是繼承自 Fruit
的所有類別所產生的實體,都可以使用 juicy
方法。
因此 Ruby 語言裡的繼承,我個人認為用分類這個詞可能會更貼切,也更精準一點,不過既然前面都有這麼多大大的貼文了,就虛(ㄐ一ㄤ)心(ㄐ一ㄡˋ)接受這個詞吧!
再來看一些程式碼吧!
先定義一個叫 Animal
的類別,並在這個 Animal
類別裡定義了兩個實體方法::walk
和 :eat
:
class Animal
def walk(place)
puts "走去 #{place}!"
end
def eat(food)
puts "#{food} 好吃!"
end
end
再讓 Cat
和 Dog
類別都繼承自 Animal
類別。
class Cat < Animal
end
class Dog < Animal
end
Cat
和 Dog
類別分別創造的實體 kitty
和 woffy
:
kitty = Cat.new
woffy = Dog.new
kitty
和 woffy
居然都能使用 Animal
類別裡的方法了,這就是繼承的概念!
kitty.eat("罐罐")
woffy.eat("骨頭")
# 印出
罐罐 好吃!
骨頭 好吃!
kitty.walk("教室")
woffy.walk("交誼廳")
# 印出
走去 教室!
走去 交誼廳!
有了繼承以後,我們在撰寫程式碼時,就可以不用在同類型的類別裡重複定義相同的方法,這對工程師真是一大福音啊!
在類別裡,如果定義了一個方法和繼承自上層類別的方法重複了,那麼在呼叫時原先繼承來的方法就會被蓋掉,優先使用自己類別寫的方法:
讓我們看個例子:
class Father
def persist
puts "不放手直到夢想到手"
end
end
class Child < Father
def persist
puts "人生恰恰像馬拉松賽跑一樣"
end
end
daddy = Father.new
me = Child.new
daddy.persist
# 印出
不放手直到夢想到手
me.persist
# 印出
人生恰恰像馬拉松賽跑一樣
如此一來,當 me
在呼叫 persist
方法時,和 daddy
呼叫 persist
兩者得到的是不同的結果。(就算個性再像的父子,也有不同的人生哲學!)
今天就先到這邊啦!明天應該會介紹模組(Module),敬請期待!